package com.esd.device.controller;

import com.esd.common.pojo.R;
import com.esd.device.entity.vo.DeviceVo;
import com.esd.device.entity.vo.DustStatusVo;
import com.esd.device.service.DeviceService;
import com.esd.device.task.DeviceConstants;
import com.esd.device.utils.NumberUtils;
import com.esd.device.utils.Tcp_Utils_Nio;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 尘埃粒子计数器 控制器
 */
@Slf4j
@RestController
@RequestMapping("dust")
public class DustController {

    @Autowired
    private Tcp_Utils_Nio tcpUtilsNio ;

    @PostMapping("searchDetail")
    public R searchDetail(@RequestBody DeviceVo deviceVo){
        String stationId = deviceVo.getStationId();
        String command = NumberUtils.longToHexString(Long.parseLong(stationId) , 2) + " 03 00 00 00 1A";
        String command2 = NumberUtils.longToHexString(Long.parseLong(stationId) , 2) + " 03 00 70 00 0C";
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String tcpResult = null ;
        String tcpResult2 = null ;
        try {
            tcpResult = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        try {
            TimeUnit.MILLISECONDS.sleep(20);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        reentrantLock.lock();
        try {
            tcpResult2 = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command2 , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (tcpResult != null && tcpResult2 != null) {
            if (tcpResult.equals("error") || tcpResult2.equals("error")) {
                return R.error("可能网关停机了，请检查");
            } else if (tcpResult.isEmpty() || tcpResult2.isEmpty()) {
                return R.error("无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
            } else {
                String[] ss1 = tcpResult.split(" ");
                String[] ss2 = tcpResult2.split(" ");
                long data1 = NumberUtils.hexToLong(ss1[5] + ss1[6])* 65536L + NumberUtils.hexToLong(ss1[3]+ss1[4]); // 0.3um个数
                long data2 = NumberUtils.hexToLong(ss1[9] + ss1[10])* 65536L + NumberUtils.hexToLong(ss1[7]+ss1[8]); // 0.5um个数
                long data3 = NumberUtils.hexToLong(ss1[13] + ss1[14])* 65536L + NumberUtils.hexToLong(ss1[11]+ss1[12]); // 1.0um个数
                long data4 = NumberUtils.hexToLong(ss1[17] + ss1[18])* 65536L + NumberUtils.hexToLong(ss1[15]+ss1[16]); // 2.5um个数
                long data5 = NumberUtils.hexToLong(ss1[21] + ss1[22])* 65536L + NumberUtils.hexToLong(ss1[19]+ss1[20]); // 5.0um个数
                long data6 = NumberUtils.hexToLong(ss1[25] + ss1[26])* 65536L + NumberUtils.hexToLong(ss1[23]+ss1[24]); // 10.0um个数

                long max1 = NumberUtils.hexToLong(ss2[5] + ss2[6])* 65536L + NumberUtils.hexToLong(ss2[3]+ss2[4]); // 0.3um个数
                long max2 = NumberUtils.hexToLong(ss2[9] + ss2[10])* 65536L + NumberUtils.hexToLong(ss2[7]+ss2[8]); // 0.5um个数
                long max3 = NumberUtils.hexToLong(ss2[13] + ss2[14])* 65536L + NumberUtils.hexToLong(ss2[11]+ss2[12]); // 1.0um个数
                long max4 = NumberUtils.hexToLong(ss2[17] + ss2[18])* 65536L + NumberUtils.hexToLong(ss2[15]+ss2[16]); // 2.5um个数
                long max5 = NumberUtils.hexToLong(ss2[21] + ss2[22])* 65536L + NumberUtils.hexToLong(ss2[19]+ss2[20]); // 5.0um个数
                long max6 = NumberUtils.hexToLong(ss2[25] + ss2[26])* 65536L + NumberUtils.hexToLong(ss2[23]+ss2[24]); // 10.0um个数

                int level = NumberUtils.hexToInt(ss1[ss1.length-3]) ; // 洁净等级
                Map<String , String> result = new HashMap<>() ;
                String status1 = data1>= max1 ? "报警":"正常" ;
                String status2 = data2>= max2 ? "报警":"正常" ;
                String status3 = data3>= max3 ? "报警":"正常" ;
                String status4 = data4>= max4 ? "报警":"正常" ;
                String status5 = data5>= max5 ? "报警":"正常" ;
                String status6 = data6>= max6 ? "报警":"正常" ;
                result.put("data1", data1 + " PCS/L,  " + status1 );
                result.put("data2", data2 + " PCS/L,  " + status2 );
                result.put("data3", data3 + " PCS/L,  " + status3 );
                result.put("data4", data4 + " PCS/L,  " + status4 );
                result.put("data5", data5 + " PCS/L,  " + status5 );
                result.put("data6", data6 + " PCS/L,  " + status6 );
                if (level == 8){
                    result.put("level", "十万级/CLASS  " + level);
                } else if (level > 8) {
                    result.put("level", "百万级/CLASS  " + level);
                }else {
                    result.put("level", "<十万级/CLASS  " + level);
                }
                return R.ok(result);
            }
        }else {
            return R.error("数据查询失败!!");
        }
    }

    @PostMapping("/samplingOn/{status}")
    public R samplingOn(
            @RequestBody DeviceVo deviceVo ,
            @PathVariable Integer status
    ){
        String stationId = deviceVo.getStationId();
        String command = NumberUtils.longToHexString(Long.parseLong(stationId) , 2) + " 06 00 32 00 0" + status;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String tcpResult = null ;
        try {
            tcpResult = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        String statusStr = status == 1 ? "开启":"停止" ;
        if (tcpResult !=null) {
            if (tcpResult.equals("error")) {
                return R.error("可能网关停机了，请检查");
            } else if (tcpResult.isEmpty()) {
                return R.error("无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
            } else {
                return R.ok("采样" + statusStr + "成功！！");
            }
        }else {
            return R.error("采样" + statusStr + "失败!!");
        }
    }

    @PostMapping("/dustClockOn/{status}")
    public R dustClockOn(
            @RequestBody DeviceVo deviceVo ,
            @PathVariable Integer status
    ){
        String stationId = deviceVo.getStationId();
        String command = NumberUtils.longToHexString(Long.parseLong(stationId) , 2) + " 06 00 7C 00 " + NumberUtils.intToHexString(status , 2);

        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String tcpResult = null ;
        try {
            tcpResult = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        String statusStr = status == 63 ? "开启":"关闭" ;
        if (tcpResult !=null) {
            if (tcpResult.equals("error")) {
                return R.error("可能网关停机了，请检查");
            } else if (tcpResult.isEmpty()) {
                return R.error("无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
            } else {
                return R.ok("报警使能" + statusStr + "成功！！");
            }
        }else {
            return R.error("报警使能" + statusStr + "失败!!");
        }
    }

    @PostMapping("/getChannelValue")
    public R getChannelValue(@RequestBody DeviceVo deviceVo){
        String stationId = deviceVo.getStationId();
        String command = NumberUtils.longToHexString(Long.parseLong(stationId) , 2) + " 03 00 70 00 0C" ;

        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String tcpResult = null ;
        try {
            tcpResult = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (tcpResult !=null) {
            if (tcpResult.equals("error")) {
                return R.error("可能网关停机了，请检查");
            } else if (tcpResult.isEmpty()) {
                return R.error("无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
            } else {
                String[] ss1 = tcpResult.split(" ");
                long data1 = NumberUtils.hexToLong(ss1[5] + ss1[6])* 65536L + NumberUtils.hexToLong(ss1[3]+ss1[4]); // 0.3um
                long data2 = NumberUtils.hexToLong(ss1[9] + ss1[10])* 65536L + NumberUtils.hexToLong(ss1[7]+ss1[8]); // 0.5um
                long data3 = NumberUtils.hexToLong(ss1[13] + ss1[14])* 65536L + NumberUtils.hexToLong(ss1[11]+ss1[12]); // 1.0um
                long data4 = NumberUtils.hexToLong(ss1[17] + ss1[18])* 65536L + NumberUtils.hexToLong(ss1[15]+ss1[16]); // 2.5um
                long data5 = NumberUtils.hexToLong(ss1[21] + ss1[22])* 65536L + NumberUtils.hexToLong(ss1[19]+ss1[20]); // 5.0um
                long data6 = NumberUtils.hexToLong(ss1[25] + ss1[26])* 65536L + NumberUtils.hexToLong(ss1[23]+ss1[24]); // 10.0um
                Map<String , Long> result = new HashMap<>() ;
                result.put("ch03" , data1) ;
                result.put("ch05" , data2) ;
                result.put("ch10" , data3) ;
                result.put("ch25" , data4) ;
                result.put("ch50" , data5) ;
                result.put("ch100" , data6) ;
                return R.ok(result) ;
            }
        }else {
            return R.error("查询失败!!");
        }
    }

    @PostMapping("/setChannelValue/{channel}/{num}")
    public R setChannelValue(
            @RequestBody DeviceVo deviceVo ,
            @PathVariable String channel ,
            @PathVariable Long num
    ){
        String stationId = deviceVo.getStationId();
        String command1 = NumberUtils.longToHexString(Long.parseLong(stationId) , 2) + " 03 00 32 00 01" ;
        ReentrantLock reentrantLock = DeviceConstants.LockMap.get(deviceVo.getServerIp());
        reentrantLock.lock();
        String tcpResult1 = "" ;
        try {
            tcpResult1 = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command1 , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (tcpResult1.equals("error")) {
            return R.error("可能网关停机了，请检查");
        } else if (tcpResult1.isEmpty()) {
            return R.error("无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
        } else {
            String s = tcpResult1.substring(12, 14);
            if (s.equals("01")){
                return R.error("请先停止采样，再设置参数！！") ;
            }
        }
        try {
            TimeUnit.MILLISECONDS.sleep(20);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        String s = NumberUtils.longToHexString(num, 8);
        String command = NumberUtils.longToHexString(Long.parseLong(stationId) , 2)
                + " 10 00 " + channel + " 00 02 04 " + s.substring(4) + s.substring(0,4) ;
        reentrantLock.lock();
        String tcpResult = "" ;
        try {
            tcpResult = tcpUtilsNio.sendCommand2(deviceVo.getServerIp() , deviceVo.getServerPort() , command , 500) ;
        } catch (Exception e) {
            log.error("加锁失败！！ {}" , e.getMessage() );
        } finally {
            reentrantLock.unlock();
        }
        if (tcpResult !=null) {
            if (tcpResult.equals("error")) {
                return R.error("可能网关停机了，请检查");
            } else if (tcpResult.isEmpty()) {
                return R.error("无返回数据，终端" + deviceVo.getStationId() + "是否正常运行？");
            } else {
                return R.ok("通道阈值设置成功！！") ;
            }
        }else {
            return R.error("查询失败!!");
        }
    }

    @Autowired
    private DeviceService deviceService ;

    @GetMapping("/getDustRows")
    public List<List<DustStatusVo>> getDustRows(){
        return deviceService.getDustRows() ;
    }
}
